{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.pipeline import FeatureUnion\n",
    "from sklearn.preprocessing import OneHotEncoder\n",
    "import copy\n",
    "from sklearn.feature_extraction import FeatureHasher\n",
    "from sklearn.cluster import KMeans\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn import preprocessing\n",
    "\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow import feature_column\n",
    "from tensorflow.keras import layers\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## File System"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "DATA_DIR =  \"/Users/jackgraham/misc/handson-ml2/datasets/unsw/\"\n",
    "testing_fname = \"UNSW_NB15_testing-set.csv\"\n",
    "training_fname = \"UNSW_NB15_training-set.csv\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reading and Feature Labeling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "df1 = pd.read_csv(DATA_DIR + training_fname)\n",
    "df2 =  pd.read_csv(DATA_DIR  + testing_fname)\n",
    "df = df1.append(df2)\n",
    "\n",
    "\n",
    "label_feature = ['attack_cat']\n",
    "categorical_features = ['proto', 'service', 'state']\n",
    "drop_features = ['id', 'sttl', 'dttl', 'swin', 'dwin', 'trans_depth', 'response_body_len', 'ct_srv_src', 'ct_state_ttl', 'ct_dst_ltm', 'ct_src_dport_ltm', 'ct_dst_sport_ltm', 'ct_dst_src_ltm', 'is_ftp_login', 'ct_ftp_cmd', 'ct_flw_http_mthd', 'ct_src_ltm', 'ct_srv_dst', 'is_sm_ips_ports', 'label']\n",
    "numerical_features = list(set(df.columns) - set(label_feature) - set(categorical_features) - set(drop_features))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[<matplotlib.axes._subplots.AxesSubplot object at 0x1424eaf10>]],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.hist(column='rate',bins=20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Normalize"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.000074</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.000078</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.000014</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.000014</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.000033</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0\n",
       "0  0.000074\n",
       "1  0.000078\n",
       "2  0.000014\n",
       "3  0.000014\n",
       "4  0.000033"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float_array = df[['rate']].values.astype(float)\n",
    "min_max_scaler = preprocessing.MinMaxScaler()\n",
    "scaled_array = min_max_scaler.fit_transform(float_array)\n",
    "df_normalized = pd.DataFrame(scaled_array)\n",
    "df_normalized.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler = preprocessing.MinMaxScaler()\n",
    "df[numerical_features] = scaler.fit_transform(df[numerical_features])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>dur</th>\n",
       "      <th>proto</th>\n",
       "      <th>service</th>\n",
       "      <th>state</th>\n",
       "      <th>spkts</th>\n",
       "      <th>dpkts</th>\n",
       "      <th>sbytes</th>\n",
       "      <th>dbytes</th>\n",
       "      <th>rate</th>\n",
       "      <th>...</th>\n",
       "      <th>ct_dst_sport_ltm</th>\n",
       "      <th>ct_dst_src_ltm</th>\n",
       "      <th>is_ftp_login</th>\n",
       "      <th>ct_ftp_cmd</th>\n",
       "      <th>ct_flw_http_mthd</th>\n",
       "      <th>ct_src_ltm</th>\n",
       "      <th>ct_srv_dst</th>\n",
       "      <th>is_sm_ips_ports</th>\n",
       "      <th>attack_cat</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.002025</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>FIN</td>\n",
       "      <td>0.000470</td>\n",
       "      <td>0.000363</td>\n",
       "      <td>0.000016</td>\n",
       "      <td>0.000012</td>\n",
       "      <td>0.000074</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Normal</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>0.010832</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>FIN</td>\n",
       "      <td>0.001221</td>\n",
       "      <td>0.003449</td>\n",
       "      <td>0.000049</td>\n",
       "      <td>0.002866</td>\n",
       "      <td>0.000078</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>Normal</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.027052</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>FIN</td>\n",
       "      <td>0.000658</td>\n",
       "      <td>0.001452</td>\n",
       "      <td>0.000024</td>\n",
       "      <td>0.000900</td>\n",
       "      <td>0.000014</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>Normal</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>0.028027</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp</td>\n",
       "      <td>FIN</td>\n",
       "      <td>0.001033</td>\n",
       "      <td>0.001089</td>\n",
       "      <td>0.000042</td>\n",
       "      <td>0.000053</td>\n",
       "      <td>0.000014</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Normal</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.007491</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>FIN</td>\n",
       "      <td>0.000845</td>\n",
       "      <td>0.000545</td>\n",
       "      <td>0.000036</td>\n",
       "      <td>0.000018</td>\n",
       "      <td>0.000033</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>40</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>39</td>\n",
       "      <td>0</td>\n",
       "      <td>Normal</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 45 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   id       dur proto service state     spkts     dpkts    sbytes    dbytes  \\\n",
       "0   1  0.002025   tcp       -   FIN  0.000470  0.000363  0.000016  0.000012   \n",
       "1   2  0.010832   tcp       -   FIN  0.001221  0.003449  0.000049  0.002866   \n",
       "2   3  0.027052   tcp       -   FIN  0.000658  0.001452  0.000024  0.000900   \n",
       "3   4  0.028027   tcp     ftp   FIN  0.001033  0.001089  0.000042  0.000053   \n",
       "4   5  0.007491   tcp       -   FIN  0.000845  0.000545  0.000036  0.000018   \n",
       "\n",
       "       rate  ...  ct_dst_sport_ltm  ct_dst_src_ltm  is_ftp_login  ct_ftp_cmd  \\\n",
       "0  0.000074  ...                 1               1             0           0   \n",
       "1  0.000078  ...                 1               2             0           0   \n",
       "2  0.000014  ...                 1               3             0           0   \n",
       "3  0.000014  ...                 1               3             1           1   \n",
       "4  0.000033  ...                 1              40             0           0   \n",
       "\n",
       "   ct_flw_http_mthd  ct_src_ltm  ct_srv_dst  is_sm_ips_ports  attack_cat  \\\n",
       "0                 0           1           1                0      Normal   \n",
       "1                 0           1           6                0      Normal   \n",
       "2                 0           2           6                0      Normal   \n",
       "3                 0           2           1                0      Normal   \n",
       "4                 0           2          39                0      Normal   \n",
       "\n",
       "   label  \n",
       "0      0  \n",
       "1      0  \n",
       "2      0  \n",
       "3      0  \n",
       "4      0  \n",
       "\n",
       "[5 rows x 45 columns]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pandas.core.series.Series"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(df['attack_cat'].unique())\n",
    "type(df['attack_cat'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[<matplotlib.axes._subplots.AxesSubplot object at 0x142ce55d0>]],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_normalized.hist(column=0,bins=20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train, Validation, Test Split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "164910 train examples\n",
      "41228 validation examples\n",
      "51535 test examples\n"
     ]
    }
   ],
   "source": [
    "train, test = train_test_split(df, test_size=0.2)\n",
    "train, val = train_test_split(train, test_size=0.2)\n",
    "print(len(train), 'train examples')\n",
    "print(len(val), 'validation examples')\n",
    "print(len(test), 'test examples')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A utility method to create a tf.data dataset from a Pandas Dataframe\n",
    "def df_to_dataset(dataframe, shuffle=True, batch_size=32):\n",
    "    # Transform name species into numerical values \n",
    "    encoder = preprocessing.LabelEncoder()\n",
    "    encoder.fit(dataframe['attack_cat'])\n",
    "    dataframe['attack_cat'] = encoder.transform(dataframe['attack_cat'])\n",
    "    dataframe['attack_cat'] = tf.keras.utils.to_categorical(dataframe['attack_cat'])\n",
    "\n",
    "    dataframe = dataframe.copy()\n",
    "    labels = dataframe.pop('attack_cat')\n",
    "    dataframe = dataframe.drop(drop_features, axis=1)\n",
    "    ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))\n",
    "    if shuffle:\n",
    "        ds = ds.shuffle(buffer_size=len(dataframe))\n",
    "    ds = ds.batch(batch_size)\n",
    "    return ds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/jackgraham/anaconda3/envs/tf2/lib/python3.7/site-packages/ipykernel_launcher.py:6: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  \n",
      "/Users/jackgraham/anaconda3/envs/tf2/lib/python3.7/site-packages/ipykernel_launcher.py:7: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  import sys\n"
     ]
    }
   ],
   "source": [
    "train_ds = df_to_dataset(train)\n",
    "val_ds = df_to_dataset(val, shuffle=False)\n",
    "test_ds = df_to_dataset(test, shuffle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Every feature: ['dur', 'proto', 'service', 'state', 'spkts', 'dpkts', 'sbytes', 'dbytes', 'rate', 'sload', 'dload', 'sloss', 'dloss', 'sinpkt', 'dinpkt', 'sjit', 'djit', 'stcpb', 'dtcpb', 'tcprtt', 'synack', 'ackdat', 'smean', 'dmean']\n",
      "A batch of labels: tf.Tensor(\n",
      "[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n",
      " 0. 0. 0. 0. 0. 0. 0. 0.], shape=(32,), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "for feature_batch, label_batch in train_ds.take(1):\n",
    "    print('Every feature:', list(feature_batch.keys()))\n",
    "    print('A batch of labels:', label_batch )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = train_ds.take(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Making Feature Columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# header is the name of the column\n",
    "# categories is all category names in that column\n",
    "# returns the one hot feature column\n",
    "def makeIndicatorFeatureColumn(header, categories):\n",
    "    r = feature_column.categorical_column_with_vocabulary_list(header, categories)\n",
    "    r_one_hot = feature_column.indicator_column(r)\n",
    "    return r_one_hot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# categorical columns\n",
    "one_hot_feature_columns = []\n",
    "for h in categorical_features:\n",
    "    fc = makeIndicatorFeatureColumn(h, df[h].unique())\n",
    "    one_hot_feature_columns.append(fc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_columns = one_hot_feature_columns\n",
    "\n",
    "# numeric columns\n",
    "for header in numerical_features:\n",
    "    feature_columns.append(feature_column.numeric_column(header))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have defined our feature columns, we will use a DenseFeatures layer to input them to our Keras model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_layer = tf.keras.layers.DenseFeatures(feature_columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Layer sequential is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because it's dtype defaults to floatx.\n",
      "\n",
      "If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.\n",
      "\n",
      "To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.\n",
      "\n",
      "WARNING:tensorflow:From /Users/jackgraham/anaconda3/envs/tf2/lib/python3.7/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:4276: IndicatorColumn._variable_shape (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead.\n",
      "WARNING:tensorflow:From /Users/jackgraham/anaconda3/envs/tf2/lib/python3.7/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:4331: VocabularyListCategoricalColumn._num_buckets (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead.\n",
      "Epoch 1/5\n",
      "5154/5154 [==============================] - 50s 10ms/step - loss: 66.3207 - accuracy: 0.1500 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00\n",
      "Epoch 2/5\n",
      "5154/5154 [==============================] - 41s 8ms/step - loss: 305.7416 - accuracy: 0.1002 - val_loss: 425.6747 - val_accuracy: 0.0000e+00\n",
      "Epoch 3/5\n",
      "5154/5154 [==============================] - 42s 8ms/step - loss: 683.4476 - accuracy: 0.0999 - val_loss: 749.8823 - val_accuracy: 0.0000e+00\n",
      "Epoch 4/5\n",
      "5154/5154 [==============================] - 42s 8ms/step - loss: 1164.0951 - accuracy: 0.1003 - val_loss: 1380.2901 - val_accuracy: 0.0000e+00\n",
      "Epoch 5/5\n",
      "5154/5154 [==============================] - 42s 8ms/step - loss: 1789.5474 - accuracy: 0.1002 - val_loss: 1600.2622 - val_accuracy: 0.0000e+00\n"
     ]
    }
   ],
   "source": [
    "model = tf.keras.Sequential([\n",
    "  feature_layer,\n",
    "  layers.Dense(128, activation='relu'),\n",
    "  layers.Dense(128, activation='relu'),\n",
    "  layers.Dense(10, activation='softmax')\n",
    "])\n",
    "\n",
    "model.compile(optimizer='adam',\n",
    "              loss='categorical_crossentropy',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "history = model.fit(train_ds,\n",
    "          validation_data=val_ds,\n",
    "          epochs=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1611/1611 [==============================] - 9s 6ms/step - loss: 1758.3268 - accuracy: 0.0000e+00\n",
      "Accuracy 0.0\n"
     ]
    }
   ],
   "source": [
    "loss, accuracy = model.evaluate(test_ds)\n",
    "print(\"Accuracy\", accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'loss': [66.18864146092598,\n",
       "  306.05370654057043,\n",
       "  683.8279913214973,\n",
       "  1163.996251743375,\n",
       "  1789.3954858900308],\n",
       " 'accuracy': [0.15003335, 0.100230426, 0.099884786, 0.100285, 0.10016373],\n",
       " 'val_loss': [117.58613750969744,\n",
       "  425.6747478665632,\n",
       "  749.8822730799069,\n",
       "  1380.2901474010862,\n",
       "  1600.2622187742436],\n",
       " 'val_accuracy': [0.0, 0.0, 0.0, 0.0, 0.0]}"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "history.history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# list all data in history\n",
    "print(history.history.keys())\n",
    "# summarize history for accuracy\n",
    "plt.plot(history.history['accuracy'])\n",
    "plt.plot(history.history['val_accuracy'])\n",
    "plt.title('model accuracy')\n",
    "plt.ylabel('accuracy')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'test'], loc='upper left')\n",
    "plt.show()\n",
    "# summarize history for loss\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'test'], loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
